package org.yunai.swjg.server.module.partner;

import org.yunai.swjg.server.core.constants.SysMessageConstants;
import org.yunai.swjg.server.entity.PartnerEntity;
import org.yunai.swjg.server.module.partner.template.PartnerTemplate;
import org.yunai.swjg.server.module.partner.vo.Partner;
import org.yunai.swjg.server.module.player.vo.Player;
import org.yunai.swjg.server.rpc.message.S_C.S_C_PartnerAddResp;
import org.yunai.swjg.server.rpc.message.S_C.S_C_PartnerDelResp;
import org.yunai.swjg.server.rpc.message.S_C.S_C_PartnerListResp;
import org.yunai.swjg.server.rpc.message.S_C.S_C_SysMessageReq;
import org.yunai.swjg.server.rpc.struct.StPartnerInfo;
import org.yunai.yfserver.spring.BeanManager;

import java.util.*;

/**
 * 玩家伙伴管理
 * User: yunai
 * Date: 13-5-30
 * Time: 下午10:17
 */
public class PartnerDiary {

    private static PartnerMapper partnerMapper;

    static {
        partnerMapper = BeanManager.getBean(PartnerMapper.class);
    }

    /**
     * 玩家信息
     */
    private Player player;
    /**
     * 伙伴集合<br />
     * KEY: 伙伴编号<br />
     * VALUE: 伙伴信息
     */
    private Map<Integer, Partner> partners;
    /**
     * 伙伴集合2<br />
     * KEY: 伙伴模版编号<br />
     * VALUE: 伙伴信息
     */
    private Map<Short, Partner> templateIdPartners;

    /**
     * 添加伙伴到伙伴集合
     *
     * @param partner 伙伴
     */
    private void addPartner(Partner partner) {
        partners.put(partner.getId(), partner);
        templateIdPartners.put(partner.getTemplate().getId(), partner);
    }

    /**
     * @return 雇佣状态的伙伴数量
     */
    public int recruitCount() {
        int count = 0;
        for (Partner partner : partners.values()) {
            if (partner.getStatus() == PartnerDef.Status.RECRUIT) {
                count++;
            }
        }
        return count;
    }

    /**
     * @param templateId 模版编号
     * @return 伙伴
     */
    public Partner getByTemplateId(short templateId) {
        return templateIdPartners.get(templateId);
    }

    /**
     * @param id 伙伴编号
     * @return 伙伴
     */
    public Partner get(int id) {
        return partners.get(id);
    }

    /**
     * @return 所有伙伴集合, 该集合无法修改
     */
    public Collection<Partner> getAll() {
        return Collections.unmodifiableCollection(partners.values());
    }

    // [业务方法BEGIN] ================================================================================================================================================================
    public PartnerDiary(Player player) {
        this.player = player;
    }

    /**
     * 加载玩家伙伴信息
     */
    public void load() {
        List<PartnerEntity> partnerEntities = partnerMapper.selectList(player.getId());
        partners = new HashMap<>(partnerEntities.size());
        templateIdPartners = new HashMap<>(partnerEntities.size());
        for (PartnerEntity entity : partnerEntities) {
            Partner partner = Partner.build(player, entity);
            addPartner(partner);
        }
    }

    /**
     * 初始化玩家伙伴信息
     */
    public void init() {
        for (Partner partner : partners.values()) {
            partner.calcRoleProps(false);
//            partner.clearPropsChanged(); // 清理下属性改变的标记
        }
    }

    /**
     * 发送伙伴信息
     */
    public void noticeInfo() {
        // 宠物列表
        List<StPartnerInfo> partnerInfos = new ArrayList<>();
        for (Partner partner : partners.values()) {
            partnerInfos.add(partner.genStPartnerInfo());
        }
        player.message(new S_C_PartnerListResp(partnerInfos));
        // 宠物属性
        for (Partner partner : partners.values()) {
            partner.noticeChangedProps(false);
            partner.noticeProps();
        }
    }

    /**
     * 雇佣伙伴<br />
     * 当该伙伴是已经雇佣，但是处于解雇状态({@link PartnerDef.Status#FIRE}时，更新为雇佣状态。<br />
     * 当该伙伴是新雇佣的，则进行一系列的初始化(宠物装备背包/宠物属性/宠物命格)
     *
     * @param template 伙伴模版
     */
    public void recruit(PartnerTemplate template) {
        Partner partner = getByTemplateId(template.getId());
        boolean newRecruit;
        if (partner != null) {
            partner.reRecruit();
            newRecruit = false;
        } else {
            partner = Partner.save(player, template);
            addPartner(partner);
            newRecruit = true;
        }
        // 告诉客户端新建宠物
        player.message(new S_C_PartnerAddResp(partner.genStPartnerInfo()));
        // 新雇佣宠物做初始化
        if (newRecruit) {
            // 宠物背包
            player.getInventory().addPartnerBag(partner);
            // TODO 计算该宠物的属性
            System.out.println("要做点事情");
        }
    }

    public void fire(Partner partner) {
        if (partner.getStatus() == PartnerDef.Status.FIRE) { // 处于解雇状态的不能在解雇拉
            player.message(new S_C_SysMessageReq(SysMessageConstants.PARTNER_STATUS_IN_FIRE));
            return;
        }
        // 解雇
        partner.fire();
        // 告诉客户端宠物解雇
        player.message(new S_C_PartnerDelResp(partner.getId()));
    }
}
